feat(marketplace): expose github.clientId from discovery + harden publish auth#271
feat(marketplace): expose github.clientId from discovery + harden publish auth#271masonjames wants to merge 2 commits intoemdash-cms:mainfrom
Conversation
🦋 Changeset detectedLatest commit: 76f8525 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
All contributors have signed the CLA ✍️ ✅ |
There was a problem hiding this comment.
Pull request overview
This PR updates EmDash’s marketplace auth/discovery and publish flow so the CLI can discover the GitHub OAuth app at runtime, while also tightening failure behavior when marketplace auth is misconfigured. It also introduces a new email:status plugin hook type/schema entry and adds targeted unit/e2e coverage.
Changes:
- Expose
github.clientIdfromGET /api/v1/auth/discoveryand harden marketplace GitHub auth routes to return clear 503s when OAuth config is missing. - Fix the CLI GitHub Device Flow requests to use
application/x-www-form-urlencoded, and add unit tests for encoding + redirect middleware DB fallback. - Add
email:statusto core hook typing, hook pipeline capability gating, and manifest validation; update docs + deploy workflow accordingly.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/marketplace/wrangler.jsonc | Documents required Worker secrets for production deploys. |
| packages/marketplace/tests/publish-e2e.test.ts | Adds e2e assertions for discovery payload and 503 behavior when OAuth config is missing. |
| packages/marketplace/src/routes/public.ts | Returns discovery payload including github.clientId. |
| packages/marketplace/src/routes/author.ts | Adds shared GitHub OAuth config validation + clearer 503 errors for misconfigurations. |
| packages/marketplace/README.md | Documents production deploy secret requirements and a post-deploy discovery check. |
| packages/core/tests/unit/redirects/middleware.test.ts | Adds unit coverage for redirect middleware DB fallback behavior. |
| packages/core/tests/unit/plugins/manifest-schema.test.ts | Ensures manifests accept the new email:status hook. |
| packages/core/tests/unit/plugins/define-plugin.test.ts | Ensures definePlugin resolves/retains email:status hooks. |
| packages/core/tests/unit/cli/publish.test.ts | Adds unit test for form-urlencoded encoding used by GitHub device flow. |
| packages/core/src/plugins/types.ts | Introduces EmailStatusEvent + EmailStatusHandler and registers the hook in types. |
| packages/core/src/plugins/manifest-schema.ts | Adds email:status to manifest hook allowlist. |
| packages/core/src/plugins/hooks.ts | Registers email:status in the pipeline and gates it behind email:provide. |
| packages/core/src/cli/commands/publish.ts | Uses discovery github.clientId, fails fast if missing, and switches GitHub device flow to form-urlencoded. |
| packages/core/src/astro/middleware/redirect.ts | Falls back to getDb() when locals.emdash isn’t available for anonymous requests. |
| docs/src/content/docs/reference/configuration.mdx | Updates plugin configuration guidance and “paired trusted/marketplace” guidance. |
| docs/src/content/docs/plugins/sandbox.mdx | Adds guidance on paired trusted + marketplace packages. |
| docs/src/content/docs/plugins/publishing.mdx | Documents paired package strategy for trusted vs sandbox-safe distributions. |
| docs/src/content/docs/plugins/installing.mdx | Adds tip about paired trusted + marketplace packages. |
| .github/workflows/deploy-marketplace.yml | Validates required secrets, pushes Worker secrets, deploys Worker, and smoke-checks discovery before seeding plugins. |
| .changeset/smooth-bugs-wave.md | Adds a patch changeset describing the hook + marketplace auth hardening. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| publicRoutes.get("/auth/discovery", (c) => { | ||
| const clientId = typeof c.env.GITHUB_CLIENT_ID === "string" ? c.env.GITHUB_CLIENT_ID : ""; | ||
| return c.json({ | ||
| github: { | ||
| clientId: c.env.GITHUB_CLIENT_ID, | ||
| clientId, | ||
| deviceAuthorizationEndpoint: "https://github.com/login/device/code", |
There was a problem hiding this comment.
/auth/discovery returns clientId without trimming. If the Worker secret contains trailing whitespace/newlines (common when copy/pasting), discovery will expose a non-empty but invalid clientId, and the CLI will proceed until GitHub rejects the request. Consider .trim() here (matching getGitHubOAuthConfig() in author routes) so whitespace-only values become an empty string.
daa6df5 to
d5ccbd5
Compare
Overlapping PRsThis PR modifies files that are also changed by other open PRs: This may cause merge conflicts or duplicated work. A maintainer will coordinate. |
|
Could you explan a bit more the rationale behind these? |
Expose the marketplace GitHub client ID via discovery only when OAuth is fully configured, fail missing OAuth config clearly, align CLI device-flow requests with GitHub's form-encoded API, and add email:status hook/schema support for email provider readiness.
61d42b5 to
27feba6
Compare
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/blocks
@emdash-cms/cloudflare
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
|
Yeah, happy to add more context here. This came out of the work to get a real SMTP/Resend provider working, plus the follow-on work to make the marketplace publish path usable. The SMTP plugin highlighted two separate but related gaps:
So the short version is: this PR is trying to upstream the pieces the SMTP/Resend work exposed — not the SMTP plugin itself, but the core/marketplace support needed for email providers and publishing. I’m happy to split the marketplace auth hardening and the Direct repo link: https://github.com/masonjames/emdash-smtp |
What does this PR do?
Hardens the marketplace GitHub auth discovery/publish flow so partial or missing OAuth configuration fails clearly instead of advertising a broken device-login path.
It also adds the
email:statushook to core typing/manifest validation, updates the deploy smoke check to requiregithub.enabled === true, and adds tests covering the discovery and manifest changes.Type of change
Checklist
pnpm typecheckpassespnpm --silent lint:json | jq '.diagnostics | length'returns 0pnpm testpasses (or targeted tests for my change)pnpm formathas been runAI-generated code disclosure
Screenshots / test output
pnpm --silent lint:quickpnpm --filter @emdash-cms/marketplace exec vitest run tests/publish-e2e.test.ts tests/manifest-schema.test.tspnpm --filter emdash exec vitest run tests/unit/cli/publish.test.ts tests/unit/plugins/define-plugin.test.ts tests/unit/plugins/manifest-schema.test.ts tests/unit/plugins/hooks.test.tspnpm typecheckpnpm --silent lint:json | jq '.diagnostics | length'